#include<iostream>
#include<unistd.h>
#include<string>
#include<thread>
#include<cstdio>
#include <cstring>




__thread int shared_value = 100;


std::string toHex(pthread_t tid)
{
    // 4. 进程内的函数，线程共享
    char buffer[64];
    snprintf(buffer, sizeof(buffer), "0x%lx", tid);
    return buffer;
}


void *start(void *args)
{
    std::string name = static_cast<const char *>(args);
    sleep(1);
    while (true)
    {
        printf("I am a new thread, name: %s, shared_value: %d,  &shared_value: %p\n", name.c_str(), shared_value, &shared_value);
        sleep(1);
    }

    return nullptr;
}


int main()
{
    pthread_attr_t attr;

    
    pthread_t tid;
    pthread_create(&tid, nullptr, start, (void *)"thread-1");
    std::cout << "I am a new thread, name: main, " << toHex(pthread_self())
              << ", NEW thread id: " << toHex(tid) << std::endl;

    while (true)
    {
        printf("main thread, shared_value: %d,  &shared_value: %p\n", shared_value, &shared_value);
        shared_value += 10;
        sleep(1);
    }
    pthread_join(tid, nullptr);
    return 0;
}








// 5.全局变量在线程内是共享的
// int gval = 100;
// #define NUM 10


// class ThreadDate
// {
// public:
//     ThreadDate()
//     {}

//     void Init(const std::string& name,int a,int b)
//     {
//         _name =name;
//         _a = a;
//         _b = b;
//     }

//     std::string Name()
//     {
//         return _name;
//     }

//     void Excute()
//     {
//         _result = _a + _b;
//     }
//     int Result(){ return _result; }

//     void SetId(pthread_t tid) { _tid = tid;}
//     int A(){return _a;}
//     int B(){return _b;}
//     pthread_t Id() { return _tid; }

//     ~ThreadDate()
//     {}

// private:
//     std::string _name;
//     int _a;
//     int _b;
//     int _result;
//     pthread_t _tid;
// };


// std::string toHex(pthread_t tid)
// {
//     // 4.进程内的函数，线程共享
//     // 独立栈
//     char buffer[64];
//     snprintf(buffer,sizeof(buffer),"0x%lx",tid);
//     return buffer;
// }


// // 被重入了
// void* routine(void* args)
// {
//     std::string name = static_cast<const char*>(args);
//     while(true)
//     {
//         // 3.不加保护的时候，显示器文件就是共享资源
//         //std::cout << "我是新线程,我的名字是: " << td->Name() << ", my tid is : " << toHex(pthread_self()) << "， 全局变量(会修改)：" << gval << std::endl;
//         sleep(1);
//         break;
//     }

//     // 8.返回值问题：返回参数，可以是变量、数字、对象
//     return 0; // 8.1线程退出方式1：线程入口函数return，表示线程退出
// }


// void* routine2(void* args)
// {
//     std::string name = static_cast<const char*>(args);
//     while(true)
//     {
//         // 3.不加保护的时候，显示器文件就是共享资源
//         std::cout << "我是新线程，名字是：" << name << "tid: "<< toHex(pthread_self()) << std::endl;
//         sleep(1);

//         // 6.线程一旦出现异常，可能会导致其他线程全部崩溃
//         // 6.1 异常的本质是信号：发出软中断，根据中断号查找中断向量表，执行中断方法，给进程发送中断信号

//         // 8.1 理论上 堆空间也是共享的 谁拿着堆空间的入口地址，谁就能访问该堆区
//         int* p = nullptr;
//         *p = 200;
//     }
// }


// int main()
// {
//     ThreadDate td[NUM];

//     for(int i = 0;i<NUM;i++)
//     {
//         char id[64];
//         snprintf(id,sizeof(id),"thread-%d",i);
//         td[i].Init(id,i*10,i*20);
//     }

//     // create threads
//     for(int i = 0;i<NUM;i++)
//     {
//         pthread_t tid;
//         pthread_create(&tid,nullptr,routine,&td[i]);
//         td->SetId(tid);
//     }

//     // wait threads
//     for(int i = 0;i < NUM;i++)
//     {
//         pthread_join(td[i].Id(),nullptr);
//     }

//     for(int i =0;i < NUM; i++)
//     {
//         printf("td[%d]: %d+%d=%d[%ld]\n", i, td[i].A(), td[i].B(), td[i].Result(), td[i].Id());
//     }

//     return 0;
// }



// 1.新线程和main线程谁先运行是不确定的
// 2.线程创建出来，要对进程的时间片进行瓜分
// int main()
// {
//     // 8.传参问题：可以是数字、变量、对象
//     pthread_t tid1;
//     //pthread_create(&tid1,nullptr,routine,(void*)"thread-1");
//     ThreadDate *td = new ThreadDate("thread-2",1,1);
//     pthread_create(&tid1,nullptr,routine,td);

//     // 7.线程创建之后，也是要等待和回收的
//     // 7.1 理由: a. 类似僵尸进程的问题  b.为了知道新线程的执行结果
//     int n = pthread_join(tid1,nullptr);
//     if(n!=0)
//     {
//         std::cerr << "join error" << n << ", " << strerror(n) << std::endl;
//         return 1;
//     }
//     else
//     {
//         std::cout << "join sucess" << std::endl;
//     }


//     // pthread_t tid2;
//     // pthread_create(&tid2,nullptr,routine,(void*)"thread-2");

//     // pthread_t tid3;
//     // pthread_create(&tid3,nullptr,routine,(void*)"thread-3");

//     // pthread_t tid4;
//     // pthread_create(&tid4,nullptr,routine,(void*)"thread-4");

//     // printf("new thread is:0x%lx\n",tid1);
//     // printf("new thread is:0x%lx\n",tid2);
//     // printf("new thread is:0x%lx\n",tid3);
//     // printf("new thread is:0x%lx\n",tid4);

//     while(true)
//     {
//         std::cout << "我是main线程..." << std::endl;
//         sleep(1);
//     }

//     return 0;
// }